/*
 * MutationStrategyGaussian.h
 *
 *  Created on: Oct 22, 2013
 *      Author: filipe
 */

#ifndef MUTATIONSTRATEGYGAUSSIAN_H_
#define MUTATIONSTRATEGYGAUSSIAN_H_

#include <cmath>
#include "MutationStrategy.h"

namespace EvolutionaryOptimization
{
	class MutationStrategyGaussian: public EvolutionaryOptimization::MutationStrategy<double>
	{
		protected:

			double _Mean;
			double _Std;

			double
			_GetRandomGaussian() const
			{
				// method to approximate a Gaussian distribution

				double norm = 1.0 / (RAND_MAX + 1.0); /* can't let u == 0 */

				double u = 1.0 - rand() * norm;
				double v = rand() * norm;
				double z = sqrt(-2.0 * log(u)) * cos(2.0 * M_PI * v);

				return (_Mean + _Std * z);
			}

			void
			_ApplyMutation(double *individual, int gene) const
			{
				individual[gene] = individual[gene] + _GetRandomGaussian();
			}

		public:

			// TODO: create a constructor to receive the mean and std
			// TODO: create a way of have one mean and std for each dimension
			MutationStrategyGaussian(int dimension) : MutationStrategy(dimension)
			{
				_Mean = 0.0;
				_Std = 0.3;
			}


			MutationStrategyGaussian(int dimension, double mean, double std) : MutationStrategy(dimension)
			{
				_Mean = mean;
				_Std = std;
			}


			~MutationStrategyGaussian()
			{
			}
	};
}

#endif
